#include "preHeader.h"
#include "SocialServerMaster.h"
#include "SocialServer.h"
#include "Session/GateServerListener.h"
#include "Session/GameServerListener.h"
#include "Session/GateServerSessionHandler.h"
#include "Session/GameServerSessionHandler.h"
#include "Session/C2GuildPacketHandler.h"
#include "Session/C2RankPacketHandler.h"
#include "Session/C2OperatingPacketHandler.h"
#include "Session/S2GuildPacketHandler.h"
#include "Session/S2RankPacketHandler.h"
#include "Session/S2OperatingPacketHandler.h"
#include "Session/DBPSessionHandler.h"
#include "Session/GateServerMgr.h"
#include "Session/GameServerMgr.h"
#include "Session/DBPSession.h"
#include "Game/PacketDispatcher.h"
#include "Game/TransMgr.h"
#include "Guild/GuildMgr.h"
#include "Rank/RankMgr.h"
#include "Operating/OperatingActivityMgr.h"

SocialServerMaster::SocialServerMaster()
{
}

SocialServerMaster::~SocialServerMaster()
{
}

bool SocialServerMaster::InitSingleton()
{
	GateServerSessionHandler::newInstance();
	GameServerSessionHandler::newInstance();
	C2GuildPacketHandler::newInstance();
	C2RankPacketHandler::newInstance();
	C2OperatingPacketHandler::newInstance();
	S2GuildPacketHandler::newInstance();
	S2RankPacketHandler::newInstance();
	S2OperatingPacketHandler::newInstance();
	DBPSessionHandler::newInstance();
	MysqlDatabasePool::newInstance();
	DatabaseMgr::newInstance();
	ShellOfGameConfig::newInstance();
	GateServerListener::newInstance();
	GameServerListener::newInstance();
	DBPSessionSingleton::newInstance();
	GateServerMgr::newInstance();
	GameServerMgr::newInstance();
	PacketDispatcher::newInstance();
	TransMgr::newInstance();
	GuildMgr::newInstance();
	RankMgr::newInstance();
	OperatingActivityMgr::newInstance();
	SocialServer::newInstance();
	return true;
}

void SocialServerMaster::FinishSingleton()
{
	GateServerSessionHandler::deleteInstance();
	GameServerSessionHandler::deleteInstance();
	C2GuildPacketHandler::deleteInstance();
	C2RankPacketHandler::deleteInstance();
	C2OperatingPacketHandler::deleteInstance();
	S2GuildPacketHandler::deleteInstance();
	S2RankPacketHandler::deleteInstance();
	S2OperatingPacketHandler::deleteInstance();
	DBPSessionHandler::deleteInstance();
	MysqlDatabasePool::deleteInstance();
	DatabaseMgr::deleteInstance();
	ShellOfGameConfig::deleteInstance();
	GateServerListener::deleteInstance();
	GameServerListener::deleteInstance();
	DBPSessionSingleton::deleteInstance();
	GateServerMgr::deleteInstance();
	GameServerMgr::deleteInstance();
	PacketDispatcher::deleteInstance();
	TransMgr::deleteInstance();
	GuildMgr::deleteInstance();
	RankMgr::deleteInstance();
	OperatingActivityMgr::deleteInstance();
	SocialServer::deleteInstance();
}

bool SocialServerMaster::InitDBPool()
{
	const auto& cfg = GetConfig();

	if (!sMysqlDatabasePool.InitWorldDB(
		cfg.GetString("WORLD_DB", "HOST", "127.0.0.1"),
		cfg.GetInteger("WORLD_DB", "PORT", 3306),
		cfg.GetString("WORLD_DB", "USER", "viewer"),
		cfg.GetString("WORLD_DB", "PASSWORD", "123456"),
		cfg.GetString("WORLD_DB", "DATABASE", "mmorpg_world"),
		1, 0))
	{
		return false;
	}

	if (!sMysqlDatabasePool.InitActvtDB(
		cfg.GetString("ACTVT_DB", "HOST", "127.0.0.1"),
		cfg.GetInteger("ACTVT_DB", "PORT", 3306),
		cfg.GetString("ACTVT_DB", "USER", "viewer"),
		cfg.GetString("ACTVT_DB", "PASSWORD", "123456"),
		cfg.GetString("ACTVT_DB", "DATABASE", "mmorpg_actvt"),
		1, 0))
	{
		return false;
	}

	return true;
}

bool SocialServerMaster::LoadDBData()
{
	const auto& cfg = GetConfig();
	sDBMgr.SetLang(cfg.GetInteger("OTHER", "LANG", 0));

	DatabaseMgr::SetupActvtDB();
	DatabaseMgr::SetupWorldDB();
	if (!sDBMgr.AsyncLoadAllTables(16)) {
		return false;
	}

	ThreadSafeQueue<std::function<bool()>> tasks;
	tasks.Enqueue([]() {
		return sShellOfGameConfig.LoadNewCfgInst();
	});
	auto threads = std::min(tasks.GetSize(), OS::GetProcNum());
	if (!sDBMgr.WaitFinishTasks(tasks, threads)) {
		return false;
	}

	return true;
}

bool SocialServerMaster::StartServices()
{
	const auto& cfg = GetConfig();
	sDBPSession.Init(
		cfg.GetString("DBP_SERVER", "HOST", "127.0.0.1"),
		cfg.GetString("DBP_SERVER", "PORT", "9990"));

	if (!sGateServerListener.Start()) {
		ELOG("--- sGateServerListener.Start() failed.");
		return false;
	}

	if (!sGameServerListener.Start()) {
		ELOG("--- sGameServerListener.Start() failed.");
		return false;
	}

	if (!sGuildMgr.Start()) {
		ELOG("--- sGuildMgr.Start() failed.");
		return false;
	}

	if (!sRankMgr.Start()) {
		ELOG("--- sRankMgr.Start() failed.");
		return false;
	}

	if (!sOperatingActivityMgr.Start()) {
		ELOG("--- sOperatingActivityMgr.Start() failed.");
		return false;
	}

	if (!sSocialServer.Start()) {
		ELOG("--- sSocialServer.Start() failed.");
		return false;
	}

	return true;
}

void SocialServerMaster::StopServices()
{
	sGateServerListener.Stop();
	sGameServerListener.Stop();
	sGuildMgr.Stop();
	sRankMgr.Stop();
	sOperatingActivityMgr.Stop();
	sSocialServer.Stop();
}

void SocialServerMaster::Tick()
{
	sDBPSession.CheckConnection();
	sMysqlDatabasePool.GetActvtDB()->CheckConnections();
	sMysqlDatabasePool.GetWorldDB()->CheckConnections();
}

std::string SocialServerMaster::GetConfigFile()
{
	return "etc/SocialServer.conf";
}

size_t SocialServerMaster::GetDeferAsyncServiceCount()
{
	return GetConfig().GetInteger("OTHER", "DEFER_ASYNC_THREAD", 1);
}

size_t SocialServerMaster::GetAsyncServiceCount()
{
	return GetConfig().GetInteger("OTHER", "ASYNC_THREAD", 1);
}

size_t SocialServerMaster::GetIOServiceCount()
{
	return GetConfig().GetInteger("OTHER", "IO_THREAD", 1);
}
